package org.example.Controller;

import org.example.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.SortParameters;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.query.SortQuery;
import org.springframework.data.redis.core.query.SortQueryBuilder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *
 * 注意：这里必须集成数据源，不然不会生效
 */
@RestController()
public class SetController {

    @Autowired
    @Qualifier("redisTemplate1")
    private RedisTemplate<String, Object> redisTemplate;


    /**
     * 去重，可以继续增加
     * http://localhost:8000/setSet?key=996&value=785
     * value可随意修改
     * @param key
     * @param value
     * @return
     */
    @RequestMapping("/setSet")
    public Long setSet(String key,String value) {
        return redisTemplate.opsForValue().getOperations().opsForSet().add(key,value,value,value);
    }






    /**
     * redis set操作
     * https://blog.csdn.net/li787974136/article/details/109643247
     * @param key
     * @return
     */
    @RequestMapping("/boundSetOps")
    public Object boundSetOps(String key) {
        BoundSetOperations boundSetOperations = redisTemplate.boundSetOps("bso");
        //添加新值后查看所有的值
        boundSetOperations.add("a","b","c");
        boundSetOperations.members().forEach(v -> System.out.println("添加新值后查看所有的值:" + v));
        //匹配获取键值对，ScanOptions.NONE为获取全部键值对；ScanOptions.scanOptions().match("c").build()匹配获取键位map1的键值对,不能模糊匹配。
        Cursor cursor = boundSetOperations.scan(ScanOptions.NONE);
        while (cursor.hasNext()){
            System.out.println("遍历所有值:" + cursor.next());
        }
// 随机获取一个值
        System.out.println("随机获取一个值:" + boundSetOperations.randomMember());
//随机获取指定数量的值
        System.out.println("随机获取指定数量的值:" + boundSetOperations.randomMembers(2));
        //获取唯一的随机数量值
        System.out.println("获取唯一的随机数量值：" + boundSetOperations.distinctRandomMembers(2));
        //比较多个特定键中的不同值
        Set list = new HashSet<>();
        list.add("bso1");
        boundSetOperations.diff(list).forEach(v -> System.out.println("比较给定集合中的set的不同元素:" + v));
        //比较2个特定键中的不同值
        boundSetOperations.diff("bso2").forEach(v -> System.out.println("比较给定set的不同元素:" + v));
        //比较键中的不同值并存储
        boundSetOperations.diffAndStore("bso2","bso3");
        redisTemplate.opsForSet().members("bso3").forEach(v -> System.out.println("比较不同set并存储:" + v));
        //比较键中的相同值
        boundSetOperations.intersect("bso2").forEach(v -> System.out.println("比较给定集合中的相同值:" + v));
        boundSetOperations.intersect(list).forEach(v -> System.out.println("比较给定集合中的相同值:" + v));
        //比较键中的相同值并存储
        boundSetOperations.intersectAndStore("bso3","bso4");
        redisTemplate.opsForSet().members("bso4").forEach(v -> System.out.println("比较给定set的相同元素:" + v));
        //将特定键中的所有值合并
        boundSetOperations.union("bso2").forEach(v -> System.out.println("将给定集合中的所有值合并:" + v));
        boundSetOperations.union(list).forEach(v -> System.out.println("将给定集合中的所有值合并:" + v));
        //将特定键中的所有值合并并存储
        boundSetOperations.unionAndStore("bso3","bso5");
        redisTemplate.opsForSet().members("bso5").forEach(v -> System.out.println("将给定集合中的所有值合并:" + v));
        //将value值转移到特定键中
        boolean moveSuc = boundSetOperations.move("bso6","a");
        System.out.println("将集合中的值移动到另外一个集合中是否成功:" + moveSuc);
        redisTemplate.opsForSet().members("bso6").forEach(v -> System.out.println("将集合中的值移动到另外一个集合中:" + v));
        boundSetOperations.members().forEach(v -> System.out.println("将集合中的值移动到另外一个集合中原集合剩余的值:" + v));
        //弹出集合中的值
        Object p = boundSetOperations.pop();
        System.out.println("弹出集合中的值:" + p);
        boundSetOperations.members().forEach(v -> System.out.println("弹出集合中的值原集合剩余的值:" + v));
        //移除特定元素
        long removeCount = boundSetOperations.remove("c");
        System.out.println("移除特定元素个数:" + removeCount);
        boundSetOperations.members().forEach(v -> System.out.println("移除特定元素个数后原集合剩余的值:" + v));
        return redisTemplate.opsForValue().getOperations().boundSetOps(key);
    }




    @RequestMapping("/opsForSet")
    public DataType opsForSet(String key) {
        //  向变量中批量添加值。
        redisTemplate.opsForSet().add("setValue","A","B","C","B","D","E","F");
//  获取变量中的值。
        Set set = redisTemplate.opsForSet().members("setValue");
        System.out.println("通过members(K key)方法获取变量中的元素值:" + set);
        //   获取变量中值的长度。
        long setLength = redisTemplate.opsForSet().size("setValue");
        System.out.println("通过size(K key)方法获取变量中元素值的长度:" + setLength);
        //   随机获取变量中的元素。
        Object randomMember = redisTemplate.opsForSet().randomMember("setValue");
        System.out.println("通过randomMember(K key)方法随机获取变量中的元素:" + randomMember);
        //  随机获取变量中指定个数的元素。
        List randomMembers = redisTemplate.opsForSet().randomMembers("setValue",2);
        System.out.println("通过randomMembers(K key, long count)方法随机获取变量中指定个数的元素:" + randomMembers);
        //  检查给定的元素是否在变量中。
        boolean isMember = redisTemplate.opsForSet().isMember("setValue","A");
        System.out.println("通过isMember(K key, Object o)方法检查给定的元素是否在变量中:" + isMember);
        //   转移变量的元素值到目的变量。
        boolean isMove = redisTemplate.opsForSet().move("setValue","A","destSetValue");
        if(isMove){
            set = redisTemplate.opsForSet().members("setValue");
            System.out.print("通过move(K key, V value, K destKey)方法转移变量的元素值到目的变量后的剩余元素:" + set);
            set = redisTemplate.opsForSet().members("destSetValue");
            System.out.println(",目的变量中的元素值:" + set);
        }
        //   弹出变量中的元素。
        Object popValue = redisTemplate.opsForSet().pop("setValue");
        System.out.print("通过pop(K key)方法弹出变量中的元素:" + popValue);
        set = redisTemplate.opsForSet().members("setValue");
        System.out.println(",剩余元素:" + set);
        //          批量移除变量中的元素。
        long removeCount = redisTemplate.opsForSet().remove("setValue","E","F","G");
        System.out.print("通过remove(K key, Object... values)方法移除变量中的元素个数:" + removeCount);
        set = redisTemplate.opsForSet().members("setValue");
        System.out.println(",剩余元素:" + set);
        //        匹配获取键值对，ScanOptions.NONE为获取全部键值对；ScanOptions.scanOptions().match("C").build()匹配获取键位map1的键值对,不能模糊匹配。
        //Cursor<Object> cursor = redisTemplate.opsForSet().scan("setValue", ScanOptions.NONE);
        Cursor<Object> cursor = redisTemplate.opsForSet().scan("setValue", ScanOptions.scanOptions().match("C").build());
        while (cursor.hasNext()){
            Object object = cursor.next();
            System.out.println("通过scan(K key, ScanOptions options)方法获取匹配的值:" + object);
        }
        //   通过集合求差值。
        List list = new ArrayList();
        list.add("destSetValue");
        Set differenceSet = redisTemplate.opsForSet().difference("setValue",list);
        System.out.println("通过difference(K key, Collection<K> otherKeys)方法获取变量中与给定集合中变量不一样的值:" + differenceSet);
        //    通过给定的key求2个set变量的差值。
        differenceSet = redisTemplate.opsForSet().difference("setValue","destSetValue");
        System.out.println("通过difference(K key, Collection<K> otherKeys)方法获取变量中与给定变量不一样的值:" + differenceSet);
        //    将求出来的差值元素保存。
        redisTemplate.opsForSet().differenceAndStore("setValue","destSetValue","storeSetValue");
        set = redisTemplate.opsForSet().members("storeSetValue");
        System.out.println("通过differenceAndStore(K key, K otherKey, K destKey)方法将求出来的差值元素保存:" + set);
        //    将求出来的差值元素保存。
        redisTemplate.opsForSet().differenceAndStore("setValue",list,"storeSetValue");
        set = redisTemplate.opsForSet().members("storeSetValue");
        System.out.println("通过differenceAndStore(K key, Collection<K> otherKeys, K destKey)方法将求出来的差值元素保存:" + set);
        //     获取去重的随机元素。
        set = redisTemplate.opsForSet().distinctRandomMembers("setValue",2);
        System.out.println("通过distinctRandomMembers(K key, long count)方法获取去重的随机元素:" + set);
        //    获取2个变量中的交集。
        set = redisTemplate.opsForSet().intersect("setValue","destSetValue");
        System.out.println("通过intersect(K key, K otherKey)方法获取交集元素:" + set);
        //    获取多个变量之间的交集。
        set = redisTemplate.opsForSet().intersect("setValue",list);
        System.out.println("通过intersect(K key, Collection<K> otherKeys)方法获取交集元素:" + set);
        //     获取2个变量交集后保存到最后一个参数上。
        redisTemplate.opsForSet().intersectAndStore("setValue","destSetValue","intersectValue");
        set = redisTemplate.opsForSet().members("intersectValue");
        System.out.println("通过intersectAndStore(K key, K otherKey, K destKey)方法将求出来的交集元素保存:" + set);
        //     获取多个变量的交集并保存到最后一个参数上。
        redisTemplate.opsForSet().intersectAndStore("setValue",list,"intersectListValue");
        set = redisTemplate.opsForSet().members("intersectListValue");
        System.out.println("通过intersectAndStore(K key, Collection<K> otherKeys, K destKey)方法将求出来的交集元素保存:" + set);
        //     获取2个变量的合集。
        set = redisTemplate.opsForSet().union("setValue","destSetValue");
        System.out.println("通过union(K key, K otherKey)方法获取2个变量的合集元素:" + set);
        //    获取多个变量的合集。
        set = redisTemplate.opsForSet().union("setValue",list);
        System.out.println("通过union(K key, Collection<K> otherKeys)方法获取多个变量的合集元素:" + set);
        //    获取2个变量合集后保存到最后一个参数上。
        redisTemplate.opsForSet().unionAndStore("setValue","destSetValue","unionValue");
        set = redisTemplate.opsForSet().members("unionValue");
        System.out.println("通过unionAndStore(K key, K otherKey, K destKey)方法将求出来的交集元素保存:" + set);
        //    获取多个变量的合集并保存到最后一个参数上。
        redisTemplate.opsForSet().unionAndStore("setValue",list,"unionListValue");
        set = redisTemplate.opsForSet().members("unionListValue");
        System.out.println("通过unionAndStore(K key, Collection<K> otherKeys, K destKey)方法将求出来的交集元素保存:" + set);
        return redisTemplate.type(key);
    }





}
